package com.bdqn.service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bdqn.mapper.UserMapper;
import com.bdqn.pojo.User;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * UserServiceImpl
 *
 * @author LILIBO
 * @since 2023-12-18
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    /**
     * 保存或修改用户（如果有主键ID则修改，没有则保存）
     *
     * @param user 用户
     * @return
     * @CachePut 首先执行方法体，执行完毕后根据参数设置进行缓存覆盖
     * value: 缓存名称
     * key: 缓存的键值
     * condition: 满足条件的调用，结果才会被缓存（不指定时相当于true-缓存）
     * unless: 不合适的返回，结果不缓存（不指定时相当于false-缓存）
     * 总结: 当condition=false一定不缓存；当condition=true且unless=true不缓存；当condition=true且unless=false缓存
     */
    @Override
    @CachePut(value = "user", key = "#user.usrId", condition = "#user!=null", unless = "#result==null")
    @CacheEvict(value = "userPage", allEntries = true)
    public User saveUser(User user) {
        boolean isok = super.saveOrUpdate(user); // 使用MyBatis-Plus提供的方法
        if (isok) {
            return super.getById(user.getUsrId());
        }
        return null;
    }

    /**
     * 根据ID删除用户
     *
     * @param usrId
     */
    @Override
    @CacheEvict(value = "userPage", allEntries = true)
    public boolean deleteUser(Long usrId) {
        return super.removeById(usrId);
    }


    /**
     * 通过用户ID获取用户对象
     *
     * @param usrId
     * @return
     */
    @Override
    @Cacheable(value = "user", keyGenerator = "keyGenerator")
    public User getUser(Long usrId) {
        return baseMapper.selectById(usrId);
    }

    /**
     * 根据用户名查找用户及对应的角色
     *
     * @param usrName
     * @return
     * @Cacheable 首先查缓存有就返回，没有就执行方法，方法返回不为空添加缓存
     * value: 缓存名称，可以多个
     * key: 缓存的键值
     * condition: 满足条件的调用，结果才会被缓存（不指定时相当于true-缓存）
     * unless: 不合适的返回，结果不缓存（不指定时相当于false-缓存）
     * 总结: 当condition=false一定不缓存；当condition=true且unless=true不缓存；当condition=true且unless=false缓存
     */
    @Override
    @Cacheable(value = "user", key = "#usrName", condition = "#usrName != null", unless = "#result==null")
    public User getByUsrName(String usrName) {
        return userMapper.getByUsrName(usrName);
    }

    /**
     * 用户名密码登录
     *
     * @param usrName 用户名
     * @param usrPassword 密码
     * @return
     */
    @Override
    public User login(String usrName, String usrPassword) {
        if (usrName == null || usrPassword == null) {
            return null;
        }
        User user = userMapper.getByUsrName(usrName);
        if (user == null) {
            return null;
        }
        if (!usrPassword.equals(user.getUsrPassword())) {
            return null;
        }
        return user;
    }

    /**
     * 分页获得用户数据
     *
     * @Cacheable 首先查缓存有就返回，没有就执行方法，方法返回不为空添加缓存
     * value: 缓存名称，可以多个
     * key: 缓存的键值
     * keyGenerator = "keyGenerator": 缓存的key自动生成
     * condition: 满足条件的调用，结果才会被缓存（不指定时相当于true-缓存）
     * unless: 不合适的返回，结果不缓存（不指定时相当于false-缓存）
     * 总结: 当condition=false一定不缓存；当condition=true且unless=true不缓存；当condition=true且unless=false缓存
     */
    @Override
    @Cacheable(value = "userPage", key = "#page.getCurrent() + '-' + #page.getSize() + '-' + #usrName + '-' + #roleId", condition = "#page.getCurrent() != null and #page.getSize() != null", unless = "#result == null")
    public Page<User> getPage(String usrName, Long roleId, Page page) {
        return userMapper.getPage(usrName, roleId, page);
    }

    /**
     * 加密算法（MD5+盐值加密1024次）
     *
     * @param plaintextPassword
     * @return
     * @throws IllegalArgumentException
     */
    @Override
    public String encryptPassword(String plaintextPassword) throws IllegalArgumentException {
        String salt = "czkt";
        Md5Hash md5Hash = new Md5Hash(plaintextPassword, salt, 1024);
        System.out.println(md5Hash);
        return md5Hash.toString();
    }

}
